package nl.harmidi.midi;

import java.util.prefs.Preferences;

import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;

import org.grlea.log.SimpleLogger;

public class MyMidiEventsLatencyListener implements MyMidiEventsListenerInterface {
	private static final SimpleLogger log = new SimpleLogger(MyMidiEventsLatencyListener.class);

	protected static long latency = 0;

	protected DelayedRunnable DelayedRunnable;

	protected static long extraLatency;

	protected static ThreadPoolingService threadPoolingService;

	static {
		extraLatency = Preferences.userRoot().getLong("latency.extra", 0);

		try {
			latency = (MidiSystem.getSynthesizer().getLatency() / 100);
			log.debugObject("Synth latency in ms",  latency );
			latency += extraLatency;
			threadPoolingService = new ThreadPoolingService();
		} catch (MidiUnavailableException e) {
			e.printStackTrace();
		}
	}

	public boolean send(MyMidiEvent myMidiEvent) {
		DelayedRunnable = new DelayedRunnable(latency, myMidiEvent);
		threadPoolingService.execute(DelayedRunnable);
		return false;
	}

	public void handleEvent(MyMidiEvent mme) {
	};

	private class DelayedRunnable implements Runnable {
		long howLong;

		MyMidiEvent event;

		public DelayedRunnable(long howLong, MyMidiEvent eventToPrint) {
			this.howLong = howLong;
			this.event = eventToPrint;
		}

		public void run() {
			sleep(howLong);
			handleEvent(event);
		}
	}

	public static void setLatency(long latencyMillis) {
		latency = latencyMillis;
	}

	public static long getLatency() {
		return latency;
	}

	protected void sleep(long millis) {
		try {
			Thread.sleep(millis);
		} catch (InterruptedException ignore) {
		}
	}

}
